// Copyright (c) 1996-2002 John Lyon-Smith. All rights reserved.

#pragma once

#include <wxtl\handle.h>

namespace wxtl
{
	class SyncObject : public Handle
	{
	public:
		SyncObject() throw() :
			Handle()
		{
		}
		explicit SyncObject( HANDLE h ) throw() :
			Handle(h)
		{
		}
		SyncObject( SyncObject& h ) throw() : 
			Handle(h)
		{
		}
		virtual ~SyncObject() throw()
		{
		}

		SyncObject& operator=(SyncObject& h) throw()
		{
			return (SyncObject&)Handle::operator=(h);
		}

		bool wait(DWORD dwTimeout = INFINITE)
		{
			_ASSERTE(isValid());
			return (WaitForSingleObject(m_h, dwTimeout) == WAIT_OBJECT_0);
		}

		enum { npos = -1 };

		static int waitMultiple(size_t count, SyncObject* pObjs[], 
			DWORD dwTimeout = INFINITE, bool bAll = false)
		{
			HANDLE *pHandles = new HANDLE[count];

			for (size_t i = 0; i < count; i++)
				pHandles[i] = pObjs[i]->get();

			DWORD dw = WaitForMultipleObjects((DWORD)count, pHandles, bAll, dwTimeout);

			delete [] pHandles;

			if (WAIT_OBJECT_0 <= dw && dw <= (WAIT_OBJECT_0 + count - 1))
				return dw - WAIT_OBJECT_0;
			else
				return npos;
		}

		static int waitMultipleMsg(size_t count, SyncObject* pObjs[], 
			DWORD dwTimeout = INFINITE, bool bAll = false, DWORD dwMask = QS_ALLINPUT)
		{
			HANDLE *pHandles = new HANDLE[count];

			for (size_t i = 0; i < count; i++)
				pHandles[i] = pObjs[i]->get();

			DWORD dw = ::MsgWaitForMultipleObjects((DWORD)count, pHandles, (bAll == true), dwTimeout, dwMask);

			delete [] pHandles;

			if (WAIT_OBJECT_0 <= dw && dw <= (WAIT_OBJECT_0 + count))
				return dw - WAIT_OBJECT_0;
			else
				return npos;
		}
	};
}

